<template>
  <ve-popup v-model="isShow" class="custom-popup">
    <view
      class="u-toast"
      :class="[isShow ? 'u-show' : '', 'u-type-' + tmpConfig.type, 'u-position-' + tmpConfig.position]"
      :style="{
        zIndex: uZIndex,
      }"
    >
      <view class="custom-loading" v-if="tmpConfig.type == 'loading'"><ve-icon name="loading" size="38" /></view>
      <view>
        <text class="u-text">{{ tmpConfig.title }}</text>
      </view>
    </view>
  </ve-popup>
</template>

<script>
  /**
   * toast 消息提示
   * @description 此组件表现形式类似uni的uni.showToastAPI，但也有不同的地方。
   * @tutorial https://www.uviewui.com/components/toast.html
   * @property {String} z-index toast展示时的z-index值
   * @event {Function} show 显示toast，如需一进入页面就显示toast，请在onReady生命周期调用
   * @example <u-toast ref="uToast" />
   */
  export default {
    name: 've-toast',
    props: {
      // z-index值
      zIndex: {
        type: [Number, String],
        default: '',
      },
    },
    data() {
      return {
        isShow: false,
        timer: null, // 定时器
        config: {
          title: '', // 显示文本
          type: '', // 主题类型，primary，success，error，warning，black loading
          duration: 2000, // 显示的时间，毫秒
          isTab: false, // 是否跳转tab页面
          url: '', // toast消失后是否跳转页面，有则跳转，优先级高于back参数
          icon: true, // 显示的图标
          position: 'center', // toast出现的位置
          callback: null, // 执行完后的回调函数
          back: false, // 结束toast是否自动返回上一页
        },
        tmpConfig: {}, // 将用户配置和内置配置合并后的临时配置变量
      }
    },
    computed: {
      uZIndex() {
        // 显示toast时候，如果用户有传递z-index值，有限使用
        return this.isShow ? (this.zIndex ? this.zIndex : 999) : '999999'
      },
    },
    methods: {
      // 显示toast组件，由父组件通过this.$refs.xxx.show(options)形式调用
      show(options) {
        // 不降结果合并到this.config变量，避免多次条用u-toast，前后的配置造成混论
        this.tmpConfig = { ...this.config, ...options }
        if (this.timer) {
          // 清除定时器
          clearTimeout(this.timer)
          this.timer = null
        }
        this.isShow = true
        this.timer = setTimeout(() => {
          // 倒计时结束，清除定时器，隐藏toast组件
          this.isShow = false
          clearTimeout(this.timer)
          this.timer = null
          // 判断是否存在callback方法，如果存在就执行，把beforePage传入
          if (typeof this.tmpConfig.callback === 'function') {
            let pages = getCurrentPages() // 当前页面
            let beforePage = pages[pages.length - 2] // 前一个页面
            this.tmpConfig.callback(beforePage)
          }
          this.timeEnd()
        }, this.tmpConfig.duration)
      },
      // 隐藏toast组件，由父组件通过this.$refs.xxx.hide()形式调用
      hide() {
        this.isShow = false
        if (this.timer) {
          // 清除定时器
          clearTimeout(this.timer)
          this.timer = null
        }
      },
      // 倒计时结束之后，进行的一些操作
      timeEnd() {
        if (this.tmpConfig.back) {
          // 回退到上一页
          this.$u.route({
            type: 'back',
          })
        }
      },
      // 开启 loading
      showLoading(options = {}) {
        this.show({
          ...{
            type: 'loading',
            title: '正在加载',
            duration: 900 * 1000,
          },
          ...options,
        })
      },
      hideLoading() {
        this.hide()
      },
    },
  }
</script>

<style lang="scss" scoped>
  @mixin vue-flex($direction: row) {
    /* #ifndef APP-NVUE */
    display: flex;
    flex-direction: $direction;
    /* #endif */
  }
  $u-type-primary: #2979ff;

  .u-toast {
    position: fixed;
    z-index: -1;
    transition: opacity 0.3s;
    text-align: center;
    color: #fff;
    border-radius: 8rpx;
    background: #585858;
    @include vue-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: 28rpx;
    opacity: 0;
    pointer-events: none;
    padding: 18rpx 40rpx;
  }

  .u-toast.u-show {
    opacity: 1;
  }

  .u-icon {
    margin-right: 10rpx;
    @include vue-flex;
    align-items: center;
    line-height: normal;
  }

  .u-position-center {
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    /* #ifndef APP-NVUE */
    max-width: 70%;
    /* #endif */
  }

  .u-position-top {
    left: 50%;
    top: 20%;
    transform: translate(-50%, -50%);
  }

  .u-position-bottom {
    left: 50%;
    bottom: 20%;
    transform: translate(-50%, -50%);
  }

  .u-type-primary {
    color: #2979ff;
    background-color: #ecf5ff;
    border: 1px solid rgb(215, 234, 254);
  }

  .u-type-success {
    color: #19be6b;
    background-color: #dbf1e1;
    border: 1px solid #bef5c8;
  }

  .u-type-error {
    color: #fa3534;
    background-color: #fef0f0;
    border: 1px solid #fde2e2;
  }

  .u-type-warning {
    color: #ff9900;
    background-color: #fdf6ec;
    border: 1px solid #faecd8;
  }

  .u-type-info {
    color: #909399;
    background-color: #f4f4f5;
    border: 1px solid #ebeef5;
  }

  .u-type-default {
    color: #fff;
    background-color: #585858;
  }
  .custom-popup {
    :deep(.ve-popup-mask) {
      background-color: rgba(0, 0, 0, 0);
    }
  }
  .custom-loading {
    :deep(.ve-icon) {
      animation: arco-loading-circle 1s infinite cubic-bezier(0, 0, 1, 1);
    }
    display: block;
    margin-bottom: 14rpx;
  }
  @keyframes arco-loading-circle {
    0% {
      transform: rotate(0);
    }

    to {
      transform: rotate(360deg);
    }
  }
</style>
